﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using HodhodNews.Exceptions;
using HodhodNews;
using System.Web;
using Googler.BLL;
using Googler.DAL;

namespace HodhodNews.Controllers
{
    /// <summary>
    /// Controls actions needed to interact with user data
    /// </summary>
    public class UserController
    {
        DataContext _Context;
        public DataContext Context
        {
            get
            {
                if (_Context == null)
                {
                    _Context = new DataContext();
                }
                return _Context;
            }
        }

        public UserController()
        {

        }
        /// <summary>
        /// Returns ID of current user, or default user if no logged-in user detected
        /// </summary>
        /// <returns></returns>
        public Guid GetUserIdOrDefault()
        {
            bool isCurrentUserAuthenticated = HttpContext.Current.User.Identity.IsAuthenticated;
            Guid userId = Guid.Empty;

            if (isCurrentUserAuthenticated)
            {
                var user = Membership.GetUser();
                if (user == null)
                {
                    userId = Guid.Empty;
                }
                else
                {
                    userId = (Guid)user.ProviderUserKey;
                }
            }
            else
            {
                var user = Membership.GetUser(Consts.DefaultUser);
                if (user == null)
                {
                    userId = this.InstallDefaultUser();
                }
                else
                {
                    userId = (Guid)user.ProviderUserKey;
                }
            }
            return userId;
        }

        /// <summary>
        /// Returns keywords belongs to current user, or default user if no logged-in user detected
        /// </summary>
        /// <returns>List of user keywords</returns>
        public List<Keyword> GetKeywords()
        {
            return this.GetKeywords(true);
        }

        /// <summary>
        /// Returns keywords belongs to current user, or default user if no logged-in user detected
        /// </summary>
        /// <param name="excludeDeletedKeywords">True to avoid deleted keywords, False to load all user keywords</param>
        /// <returns>List of user keywords</returns>
        public List<Keyword> GetKeywords(bool excludeDeletedKeywords)
        {
            Guid userId = this.GetUserIdOrDefault();

            var qurey = this.Context.UserKeywords
                .Where(uk => uk.UserId == userId);

            if (excludeDeletedKeywords)
            {
                qurey = qurey.Where(uk => uk.IsDeleted == null || uk.IsDeleted == false);
            }

            return qurey.Select(uk => uk.Keyword).ToList();
        }

        public UserKeyword GetUserKeyword(string keyword)
        {
            keyword = keyword.ToLower();

            var userId = this.GetUserIdOrDefault();
            var userKeyword = this.Context.UserKeywords
                .Where(uk => uk.UserId == userId)
                .Where(uk => uk.Keyword.Name.ToLower() == keyword)
                .FirstOrDefault();

            return userKeyword;
        }

        /// <summary>
        /// Adds keyword to get its news for current user
        /// </summary>
        /// <param name="keyword">Keyword to get its news</param>
        public void AddKeyword(string keyword)
        {
            var userKeywordRelation = this.GetUserKeyword(keyword);
            if (userKeywordRelation == null)
            {
                var loadedKeyword = this.Context.Keywords.Where(k => k.Name == keyword).FirstOrDefault();
                if (loadedKeyword == null)
                {
                    loadedKeyword = new Keyword();
                    loadedKeyword.Name = keyword;

                    this.Context.AddToKeywords(loadedKeyword);
                    this.Context.SaveChanges();
                }
                AttachKeywordToUser(loadedKeyword);

            }
            else
            {
                if (userKeywordRelation.IsDeleted == null || userKeywordRelation.IsDeleted == false)
                {
                    return;
                }
                else
                {
                    userKeywordRelation.IsDeleted = false;
                    this.Context.SaveChanges();
                    this.Context.Detach(userKeywordRelation);
                }
            }
        }
        /// <summary>
        /// Establish a realtionship between current user and the provided keyword
        /// </summary>
        /// <param name="keyword"></param>
        private void AttachKeywordToUser(Keyword keyword)
        {
            keyword.UserKeywords.Add(new UserKeyword()
            {
                KeywordID = keyword.ID,
                UserId = this.GetUserIdOrDefault()
            });

            this.Context.SaveChanges();
            this.Context.Detach(keyword);
        }

        /// <summary>
        /// Create new user in hodhod to be used as default user, returns empty Guid if default user is already installed
        /// </summary>
        /// <returns></returns>
        public Guid InstallDefaultUser()
        {
            if (Membership.GetUser(Consts.DefaultUser) == null)
            {
                var user = Membership.CreateUser(Consts.DefaultUser, "HodhodFlyHigh1234567", "hodhod2030@gmail.com");
                return (Guid)user.ProviderUserKey;
            }
            return Guid.Empty;
        }

        /// <summary>
        /// Deactivate the realtionship between current user and the provided keyword
        /// </summary>
        /// <param name="id">ID of keyword</param>
        public void RemoveKeywork(int id)
        {
            var userId = this.GetUserIdOrDefault();
            var keyword = Context.UserKeywords
                .Where(k => k.KeywordID == id)
                .Where(k => k.UserId == userId)
                .FirstOrDefault();

            if (keyword != null)
            {
                keyword.IsDeleted = true;
                Context.SaveChanges();
                Context.Detach(keyword);
            }
        }
    }
}
